﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StockFinder.Model;

namespace StockFinder.Indicators.Day.ClosePrice
{
    public class ExponentialMovingAverageTrueRangePercentOfClosePriceDayIndicator : BaseDayIndicator
    {
        public ExponentialMovingAverageTrueRangePercentOfClosePriceDayIndicator(int lookbackPeriod, string indicatorName) : base(lookbackPeriod, indicatorName)
        {
        }

        public override void ApplyIndicator(List<DailyPrice> prices)
        {
            if (!Initialize(prices)) return;

            decimal averageTrueRange = 0M;
            decimal cummulativeTrueRange = 0M;
            var orderedPrices = prices.OrderBy(p => p.PriceDate);
            DailyPrice currentPrice, previousPrice;

            var pricesArray = orderedPrices.ToArray();
            var pricesArrayCount = pricesArray.Count();            

            //array
            for (int i = 0; i < pricesArrayCount; i++)
            {
                currentPrice = pricesArray[i];

                var highLow = currentPrice.AdjustedHigh - currentPrice.AdjustedLow;

                decimal trueRange = 0M;
                if (i == 0)
                {
                    trueRange = highLow;
                }
                else
                {
                    previousPrice = pricesArray[i - 1];

                    var highPrevClose = Math.Abs(currentPrice.AdjustedHigh - previousPrice.AdjustedClose);

                    var lowPrevClose = Math.Abs(currentPrice.AdjustedLow - previousPrice.AdjustedClose);

                    trueRange = Math.Max(highLow, Math.Max(highPrevClose, lowPrevClose));
                }

                cummulativeTrueRange += trueRange;

                if (i == 13)
                {
                    averageTrueRange = (cummulativeTrueRange / 14);

                    var atr = Math.Round(averageTrueRange, 2);
                    currentPrice.DayIndicators[IndicatorName] = Math.Round(((atr / currentPrice.AdjustedClose) * 100), 2);
                }

                if (i > 13)
                {
                    averageTrueRange = ((averageTrueRange * 13) + trueRange) / 14;

                    var atr = Math.Round(averageTrueRange, 2);
                    currentPrice.DayIndicators[IndicatorName] = Math.Round(((atr / currentPrice.AdjustedClose) * 100), 2);
                }
            }
        }
    }
}
